#include "alg.h"

void Algorithm::initSigs(void){
	for(int i=0; i<Ci->signalSize(); ++i)
		Ci->getSignal(i)->init();
	return;
}

void Algorithm::initTracedSigs(void){
	for(unsigned i=0; i<tracedSigs.size(); ++i){
		tracedSigs[i]->setTraced(true);
		tracedSigs[i]->setSV1(1);
		tracedSigs[i]->setSV0(1);
		tracedSigs[i]->computeV1();
		tracedSigs[i]->computeV0();
		
		if(tracedSigs[i]->getInput(0)->signature()!=OUTPUT){
			tracedSigs[i]->getInput(0)->getInput(1)->setTraced(true);
			tracedSigs[i]->getInput(0)->getInput(1)->setSV1(1);
			tracedSigs[i]->getInput(0)->getInput(1)->setSV0(1);
			tracedSigs[i]->getInput(0)->getInput(1)->computeV1();
			tracedSigs[i]->getInput(0)->getInput(1)->computeV0();
			tracedSigs[i]->getInput(0)->setVisited(true);
			tracedSigs[i]->getInput(0)->setBackwardVisited(true);
		}
		else{
			tracedSigs[i]->getInput(1)->getInput(1)->setTraced(true);
			tracedSigs[i]->getInput(1)->getInput(1)->setSV1(1);
			tracedSigs[i]->getInput(1)->getInput(1)->setSV0(1);
			tracedSigs[i]->getInput(1)->getInput(1)->computeV1();
			tracedSigs[i]->getInput(1)->getInput(1)->computeV0();
			tracedSigs[i]->getInput(1)->setVisited(true);
			tracedSigs[i]->getInput(1)->setBackwardVisited(true);
		}
	}
	return;
}

void Algorithm::printTraces(void){
	cout<<"trace signals={";
	for(unsigned i=0; i<tracedSigs.size(); ++i){
		cout<<tracedSigs[i]->getName();
		if(i<(tracedSigs.size()-1))
			cout<<",";
        }
        cout<<"}"<<endl;
}

void Algorithm::initGates(void){
	for(int i=0; i<Ci->gateSize(); ++i){
		Ci->getGate(i)->setVisited(false);
		Ci->getGate(i)->setBackwardVisited(false);
	}
	for(int i=0; i<Ci->flipflopSize(); ++i){
		Ci->getFlipflop(i)->setVisited(false);
		Ci->getFlipflop(i)->setBackwardVisited(false);
	}
	return;
}

void Algorithm::computeGatesP(void){
	bool cont=true;
	for(int i=0; i<Ci->inputSize(); ++i){
		Ci->getInput(i)->getInput(0)->setP1(0.5);
		Ci->getInput(i)->getInput(0)->setP0(0.5);
		
	}

	for(int i=0; i<Ci->flipflopSize(); ++i){
		FlipflopNode *f=(FlipflopNode*)Ci->getFlipflop(i);
		if(f->hasLoop()){
			for(int j=0; j<f->outputSize(); ++j){
				f->getOutput(j)->setP1(0.5);
				f->getOutput(j)->setP0(0.5);
			}
		}		
	}
	while(cont){
		cont = false;
		for(int i=0; i<Ci->signalSize(); ++i){	
			if((Ci->getSignal(i)->getP0()==0) && (Ci->getSignal(i)->getP1()==0) ){
                                Ci->getSignal(i)->computeP();
				cont=true;
			}
		}
	}
	return;	
}

float Algorithm::computeTV(void){
	TV=0;
	TVC=TVNC=0;
	for(int i=0; i<Ci->flipflopSize(); ++i){
		if(Ci->getFlipflop(i)->isCriticalFF)
			TV += Ci->getFlipflop(i)->getOutput(0)->getV();
		else
			TV += Ci->getFlipflop(i)->getOutput(0)->getV();
		if(Ci->getFlipflop(i)->isCriticalFF)
			TVC += Ci->getFlipflop(i)->getOutput(0)->getV();
		else
			TVNC += Ci->getFlipflop(i)->getOutput(0)->getV();
	}
	
	//TV=TVC;
	return TV;
}

void Algorithm::computeForwardWeight(void){
	vector<Node*> flipVec;
	for(int i=0; i<Ci->flipflopSize(); ++i){
		for(int j=0; j<flipVec.size(); ++j){
			if(flipVec[j]->getIndex()==Ci->getFlipflop(i)->getIndex())
				break;
		}
		if(Ci->getFlipflop(i)->isCriticalFF)
			Ci->getFlipflop(i)->fWeight += 1;
		initGates();
		vector<Signal*> sigVec;
		vector<Node*> nodeVec;
		sigVec.push_back(Ci->getFlipflop(i)->getOutput(0));
		nodeVec.push_back(Ci->getFlipflop(i));
		while(!sigVec.empty()){
			Signal *s=sigVec.front();
			sigVec.erase(sigVec.begin());
			for(int j=0; j<s->outputSize(); ++j){
				if(s->getOutput(j)->getVisited())
					continue;
				s->getOutput(j)->setVisited(true);
				if(s->getOutput(j)->signature()==FLIPFLOP){
					bool test=false;
					for(int k=0; k<flipVec.size(); ++k){
						if(flipVec[k]->getIndex()==s->getOutput(j)->getIndex()){
							test = true;
							for(int n=0; n<nodeVec.size(); ++n){
								nodeVec[n]->fWeight += flipVec[k]->fWeight;
							}
							break;
						}
					}
					if(!test){
						sigVec.push_back(s->getOutput(j)->getOutput(0));
						if(s->getOutput(j)->isCriticalFF){
							for(int n=0; n<nodeVec.size(); ++n){
								nodeVec[n]->fWeight += 1;
							}
						}
						nodeVec.push_back(s->getOutput(j));
					}
				}
				else
					sigVec.push_back(s->getOutput(j)->getOutput(0));
			}
		}
		for(int n=0; n<nodeVec.size(); ++n){
			flipVec.push_back(nodeVec[n]);
		}
	}
	return;
}

void Algorithm::computeBackwardWeight(void){
	vector<Node*> flipVec;
	for(int i=0; i<Ci->flipflopSize(); ++i){
		
		for(int j=0; j<flipVec.size(); ++j){
			if(flipVec[j]->getIndex()==Ci->getFlipflop(i)->getIndex())
				break;
		}
		
		if(Ci->getFlipflop(i)->isCriticalFF)
			Ci->getFlipflop(i)->bWeight += 1;
		initGates();
		vector<Signal*> sigVec;
		vector<Node*> nodeVec;
		sigVec.push_back(Ci->getFlipflop(i)->getInput(1));
		nodeVec.push_back(Ci->getFlipflop(i));
	
		while(!sigVec.empty()){
			Signal *s=sigVec.front();
			sigVec.erase(sigVec.begin());
			if(s->inputSize()==0)
				continue;
		
			if(s->getInput(0)->getVisited())
				continue;
			s->getInput(0)->setVisited(true);
			if(s->getInput(0)->signature()==FLIPFLOP){
				bool test=false;
				for(int k=0; k<flipVec.size(); ++k){
					if(flipVec[k]->getIndex()==s->getInput(0)->getIndex()){
						test = true;
						for(int n=0; n<nodeVec.size(); ++n){
							nodeVec[n]->bWeight += flipVec[k]->bWeight;
						}
						break;
					}
				}
				if(!test){
					sigVec.push_back(s->getInput(0)->getInput(0));
					if(s->getInput(0)->isCriticalFF){
						for(int n=0; n<nodeVec.size(); ++n){
							nodeVec[n]->bWeight += 1;
						}
					}
					nodeVec.push_back(s->getInput(0));
				}
			}
			else
				sigVec.push_back(s->getInput(0)->getInput(0));
		
		}
		
		for(int n=0; n<nodeVec.size(); ++n){
			flipVec.push_back(nodeVec[n]);
		}
		
	}
	return;
}
				
void Algorithm::computeForwardPathWeight(void){
	vector<Node*> flipVec;
	for(int i=0; i<Ci->flipflopSize(); ++i){
		for(int j=0; j<flipVec.size(); ++j){
			if(flipVec[j]->getIndex()==Ci->getFlipflop(i)->getIndex())
				break;
		}
		Ci->getFlipflop(i)->fWeight += Ci->getFlipflop(i)->cPathCount;
		initGates();
		vector<Signal*> sigVec;
		vector<Node*> nodeVec;
		sigVec.push_back(Ci->getFlipflop(i)->getOutput(0));
		nodeVec.push_back(Ci->getFlipflop(i));
		while(!sigVec.empty()){
			Signal *s=sigVec.front();
			sigVec.erase(sigVec.begin());
			for(int j=0; j<s->outputSize(); ++j){
				if(s->getOutput(j)->getVisited())
					continue;
				s->getOutput(j)->setVisited(true);
				if(s->getOutput(j)->signature()==FLIPFLOP){
					bool test=false;
					for(int k=0; k<flipVec.size(); ++k){
						if(flipVec[k]->getIndex()==s->getOutput(j)->getIndex()){
							test = true;
							for(int n=0; n<nodeVec.size(); ++n){
								nodeVec[n]->fWeight += flipVec[k]->fWeight;
							}
							break;
						}
					}
					if(!test){
						sigVec.push_back(s->getOutput(j)->getOutput(0));
						for(int n=0; n<nodeVec.size(); ++n){
							nodeVec[n]->fWeight += s->getOutput(j)->cPathCount;
						}
						nodeVec.push_back(s->getOutput(j));
					}
				}
				else
					sigVec.push_back(s->getOutput(j)->getOutput(0));
			}
		}
		for(int n=0; n<nodeVec.size(); ++n){
			flipVec.push_back(nodeVec[n]);
		}
	}
	return;
}

void Algorithm::computeBackwardPathWeight(void){
	vector<Node*> flipVec;
	for(int i=0; i<Ci->flipflopSize(); ++i){
		
		for(int j=0; j<flipVec.size(); ++j){
			if(flipVec[j]->getIndex()==Ci->getFlipflop(i)->getIndex())
				break;
		}
		
		Ci->getFlipflop(i)->fWeight += Ci->getFlipflop(i)->cPathCount;
		initGates();
		vector<Signal*> sigVec;
		vector<Node*> nodeVec;
		sigVec.push_back(Ci->getFlipflop(i)->getInput(1));
		nodeVec.push_back(Ci->getFlipflop(i));

		while(!sigVec.empty()){
			Signal *s=sigVec.front();
			sigVec.erase(sigVec.begin());
			//cout<<s->str()<<endl;
			if(s->inputSize()==0)
				continue;
			int index = (s->getInput(0)->signature()==OUTPUT) ? 1:0;
			if(s->getInput(index)->getVisited())
				continue;
			
			s->getInput(index)->setVisited(true);
			if(s->getInput(index)->signature()==FLIPFLOP){
				
				bool test=false;
				for(int k=0; k<flipVec.size(); ++k){
					if(flipVec[k]->getIndex()==s->getInput(index)->getIndex()){
						test = true;
						for(int n=0; n<nodeVec.size(); ++n){
							nodeVec[n]->bWeight += flipVec[k]->bWeight;
						}
						break;
					}
				}
				if(!test){
					sigVec.push_back(s->getInput(index)->getInput(0));
					if(s->getInput(index)->isCriticalFF){
						for(int n=0; n<nodeVec.size(); ++n){
							nodeVec[n]->bWeight += nodeVec[n]->cPathCount;
						}
					}
					nodeVec.push_back(s->getInput(index));
				}
			}
			else
				sigVec.push_back(s->getInput(index)->getInput(0));
		}		
		for(int n=0; n<nodeVec.size(); ++n){
			flipVec.push_back(nodeVec[n]);
		}
		
	}
	return;
}

#ifdef USEHYBRID
void Algorithm::forward1sig1cycle(Signal* sig){
	list<Signal*> sigList;
	sigList.push_back(sig);
	while(!sigList.empty()){
		sig = sigList.back();
		sigList.pop_back();
                //cout<<"forward"<<endl;
                //cout<<"Signal list"<<sig->getName()<<endl;
                
		for(int i=0; i<sig->outputSize(); i++){
			if(sig->getOutput(i)->signature()!= FLIPFLOP){

				if(sig->getOutput(i)->HG_ID == -1 && sig->getOutput(i)->getBackwardVisited())
					continue;
                                
                                //cout<<"HG ID is "<<sig->getOutput(i)->HG_ID<<endl;
                                if(sig->getOutput(i)->HG_ID != -1 && Ci->getHGate(sig->getOutput(i)->HG_ID)->getBackwardVisited())
                                {
                                        //cout<<"OHLEIOHLEIOLEIOLEI"<<endl;
                                        continue;
                                }
                                
                                // covered by a HGate
                                if(sig->getOutput(i)->HG_ID != -1)
                                {
                                        //cout<<"forard 1 cycle!!!"<<endl;
                                        float v = Ci->getHGate(sig->getOutput(i)->HG_ID)->getOutput(0)->getV();
                                        Ci->getHGate(sig->getOutput(i)->HG_ID)->forwardRestor();
                                        
                                        if(Ci->getHGate(sig->getOutput(i)->HG_ID)->getOutput(0)->getV() == v)
                                                continue;
                                        
                                        for(int j=0; j<Ci->getHGate(sig->getOutput(i)->HG_ID)->outputSize(); ++j){
                                                if(Ci->getHGate(sig->getOutput(i)->HG_ID)->getOutput(j)->getV())
                                                        sigList.push_back(Ci->getHGate(sig->getOutput(i)->HG_ID)->getOutput(j));
                                        }
                                }
                                else
                                {
                                        float v = sig->getOutput(i)->getOutput(0)->getV();
                                        sig->getOutput(i)->forwardRestor();
                                        
                                        if(sig->getOutput(i)->getOutput(0)->getV() == v)
                                                continue;
                                        
                                        for(int j=0; j<sig->getOutput(i)->outputSize(); ++j){
                                                if(sig->getOutput(i)->getOutput(j)->getV())
                                                        sigList.push_back(sig->getOutput(i)->getOutput(j));
                                        }
                                }
                        }
		}
	}
        
	return;	
}

void Algorithm::backward1sig1cycle(Signal* sig){
	list<Signal*> sigList;
	sigList.push_back(sig);
	while(!sigList.empty()){
		sig = sigList.back();
		sigList.pop_back();
                //cout<<"backward"<<endl;
                //cout<<"Signal list"<<sig->getName()<<endl;
		for(int i=0; i<sig->inputSize(); i++){
			if((sig->getInput(i)->signature()!= FLIPFLOP) && (sig->getInput(i)->signature()!= OUTPUT)){
                                
                                if(sig->getInput(i)->HG_ID == -1 && sig->getInput(i)->getBackwardVisited())
					continue;
                                
                                if(sig->getInput(i)->HG_ID != -1 && Ci->getHGate(sig->getInput(i)->HG_ID)->getBackwardVisited())
					continue;

                                // covered by a HGate
                                if(sig->getInput(i)->HG_ID != -1)
                                {
                                        //cout<<"backward 1 cycle!!!"<<endl;
                                        float v = Ci->getHGate(sig->getInput(i)->HG_ID)->getInput(0)->getV();
                                        Ci->getHGate(sig->getInput(i)->HG_ID)->backwardRestor();
                                        
                                        if(Ci->getHGate(sig->getInput(i)->HG_ID)->getInput(0)->getV() == v)
                                                continue;
                                        
                                        for(int j=0; j<Ci->getHGate(sig->getInput(i)->HG_ID)->outputSize(); ++j){
                                                if(Ci->getHGate(sig->getInput(i)->HG_ID)->getInput(j)->getV())
                                                        sigList.push_back(Ci->getHGate(sig->getInput(i)->HG_ID)->getInput(j));
                                        }
                                }
                                else
                                {
                                        float v = sig->getInput(i)->getInput(0)->getV();
                                        sig->getInput(i)->backwardRestor();
                                        
                                        if(sig->getInput(i)->getInput(0)->getV() == v)
                                                continue;
                                        
                                        for(int j=0; j<sig->getInput(i)->outputSize(); ++j){
                                                if(sig->getInput(i)->getInput(j)->getV())
                                                        sigList.push_back(sig->getInput(i)->getInput(j));
                                        }
                                }
                        }
		}
	}

	return;	
}

#else
void Algorithm::forward1sig1cycle(Signal* sig){
	list<Signal*> sigList;
	sigList.push_back(sig);
	while(!sigList.empty()){
		sig = sigList.back();
		sigList.pop_back();
		for(int i=0; i<sig->outputSize(); i++){
			if(sig->getOutput(i)->signature()!= FLIPFLOP){

				if(sig->getOutput(i)->getBackwardVisited())
					continue;
				float v = sig->getOutput(i)->getOutput(0)->getV();
				sig->getOutput(i)->forwardRestor();
				if(sig->getOutput(i)->getOutput(0)->getV()==v)
					continue;
				for(int j=0; j<sig->getOutput(i)->outputSize(); ++j){
					if(sig->getOutput(i)->getOutput(j)->getV())
						sigList.push_back(sig->getOutput(i)->getOutput(j));
				}
			}
		}
	}
	return;	
}

void Algorithm::backward1sig1cycle(Signal* sig){
	list<Signal*> sigList;
	
	sigList.push_back(sig);
	while(!sigList.empty()){
		sig = sigList.back();
		sigList.pop_back();
		for(int i=0; i<sig->inputSize(); i++){
			if((sig->getInput(i)->signature()!= FLIPFLOP) && (sig->getInput(i)->signature()!= OUTPUT)){
				if(sig->getInput(i)->getVisited())
					continue;
				float v = sig->getInput(i)->getInput(0)->getV();
				
				sig->getInput(i)->backwardRestor();
				if(sig->getInput(i)->getInput(0)->getV()==v)
					continue;
				for(int j=0; j<sig->getInput(i)->inputSize(); ++j)
					if(sig->getInput(i)->getInput(j)->getV())
						sigList.push_back(sig->getInput(i)->getInput(j));
			}
		}
	}

	return;	
}
#endif

void Algorithm::forward(void){
	float tmpTV;
	FlipflopNode *f;
	do{
		tmpTV=TV;
		for(int i=0; i<Ci->flipflopSize(); ++i){
			f = (FlipflopNode *)Ci->getFlipflop(i);
			
                        //	if(f->getBackwardVisited())
			//	continue;
			if(!f->getOutput(0)->getTraced())
				f->forwardRestor();
			if(f->getOutput(0)->getV()!=0){
                                forward1sig1cycle(f->getOutput(0));
			}
		}
		computeTV();		
	}while(TV>tmpTV);
		
	return;	
}

void Algorithm::backward(void){
	float tmpTV;
	FlipflopNode *f;
	do{
		tmpTV=TV;
		for(int i=0; i<Ci->flipflopSize(); ++i){
			f = (FlipflopNode *)Ci->getFlipflop(i);
			if(f->getV()==0)
                                continue;
			f->backwardRestor();
			backward1sig1cycle(f->getInput(1));
		}
		computeTV();
	}while(TV>tmpTV);
		
	return;	
}

void Algorithm::hybridComp(void){
	float tmpTV=0;
	vector<rateStruct>	sortedFFs;
	sortedFFs.resize(Ci->flipflopSize()*2);
	for(int i=0; i<Ci->flipflopSize(); ++i){
		
		sortedFFs[i].ff = Ci->getFlipflop(i);
		if(test_r)
			sortedFFs[i].rate = 0;
		else
			sortedFFs[i].rate = Ci->getFlipflop(i)->fWeight;
		sortedFFs[i].fb = true;
		
		sortedFFs[i+Ci->flipflopSize()].ff = Ci->getFlipflop(i);
		if(test_r)
			sortedFFs[i+Ci->flipflopSize()].rate = 0;
		else
			sortedFFs[i+Ci->flipflopSize()].rate = Ci->getFlipflop(i)->bWeight;
		sortedFFs[i+Ci->flipflopSize()].fb = false;
	}
	sort(sortedFFs.begin(), sortedFFs.end(), moreWeight());		
	
	FlipflopNode *f;
        do{
		tmpTV=TV;
                
		for(int i=0; i<sortedFFs.size(); ++i){
			if(test_r)
                                if(sortedFFs[i].ff->getOutput(0)->region != r)
                                        continue;
			f = (FlipflopNode *)sortedFFs[i].ff;
                
			if(!sortedFFs[i].fb){
				if(f->getV()==0)
					continue;
				if(!f->getOutput(0)->getTraced())
					f->backwardRestor();
				
				backward1sig1cycle(f->getInput(1));
				
			}
			else{
				if(!f->getOutput(0)->getTraced())
					f->forwardRestor();
				if(f->getV()!=0){
                                        forward1sig1cycle(f->getOutput(0));
				}
			}
		}
		
		computeTV();		
	}while(TV>tmpTV);
	
	return;	
}

void Algorithm::visCompute(void){
	float tmpTV;
	TV=TVC=TVNC=0;
	initSigs();
	initGates();
	initTracedSigs();
	//do{//for(int i=0; i<100; ++i){
	do{
                tmpTV=TV;
		
                forward();
                backward();
                //hybridComp();
        }while(TV>tmpTV);
	return;
}


void Algorithm::printAllsigs(){
        for(int i=0; i < Ci->signalSize(); ++i)
        {
                cout<<Ci->getSignal(i)->getName()<<"\t";
                cout<<"P0 "<<Ci->getSignal(i)->getP0()<<"\t";
                cout<<"P1 "<<Ci->getSignal(i)->getP1()<<"\t";
                cout<<"R0 "<<Ci->getSignal(i)->getR0()<<"\t";
                cout<<"R1 "<<Ci->getSignal(i)->getR1()<<"\t";
                cout<<"RV0 "<<Ci->getSignal(i)->getRV0()<<"\t";
                cout<<"RV1 "<<Ci->getSignal(i)->getRV1()<<"\t";
                cout<<"V0 "<<Ci->getSignal(i)->getV0()<<"\t";
                cout<<"V1 "<<Ci->getSignal(i)->getV1()<<"\t";
                cout<<"SV0 "<<Ci->getSignal(i)->getSV0()<<"\t";
                cout<<"SV1 "<<Ci->getSignal(i)->getSV1()<<"\t";
                cout<<endl;
        }       
}


#ifndef SELECTONE
void Algorithm::traceSelect(unsigned n){
            
	tracedSigs.clear();
	initSigs();
	Confset *C1,*C2;
	C2 = new Confset();
	C1 = new Confset();
	Conf *c1;
	
	for(int i=0; i<Ci->flipflopSize(); ++i){
		if(test_r)
			if(Ci->getFlipflop(i)->getOutput(0)->region != r)
				continue;
                if( (!Ci->getFlipflop(i)->getOutput(0)->getTraced())){
                        tracedSigs.push_back(Ci->getFlipflop(i)->getOutput(0));
                        visCompute();
                        c1 = new Conf();
                                                
                        for(int j=0; j<tracedSigs.size(); ++j)
                        {
                                c1->tracedSigs.push_back(tracedSigs[j]);
                        }

                        c1->TV = TV;
                        c1->TVC = TVC;
                        c1->TVNC = TVNC;
                        //c1->print();
                        //printAllsigs();
                        
                        //cout<<"TV is "<<TV<<endl;
                        //cout<<"TVC is "<<TVC<<endl;
                        //cout<<"TVNC is "<<TVNC<<endl;
                        C1->confs.push_back(c1);
                        //cout<<Ci->getFlipflop(i)->getOutput(0)->getName()<<":"<<TV<<endl;
                        tracedSigs.pop_back();
                }
        }	
	
        //C1->min();
        //C1->reduce();
	
	for(int k=1; k<n; ++k){
		delete C2;
		C2 = new Confset();
		
		for(int k1=0; k1<C1->confs.size(); ++k1){
			initSigs();
			tracedSigs.clear();	
			for(int k2=0; k2<C1->confs[k1]->tracedSigs.size(); ++k2){
				tracedSigs.push_back(C1->confs[k1]->tracedSigs[k2]);
				C1->confs[k1]->tracedSigs[k2]->setTraced(true);
			}
			
			for(int i=0; i<Ci->flipflopSize(); ++i){
				if(test_r)
                                        if(Ci->getFlipflop(i)->getOutput(0)->region != r)
                                                continue;
				if( (!Ci->getFlipflop(i)->getOutput(0)->getTraced())){//not traced
					tracedSigs.push_back(Ci->getFlipflop(i)->getOutput(0));
					visCompute();
					c1 = new Conf();
					for(int j=0; j<tracedSigs.size(); ++j)
						c1->tracedSigs.push_back(tracedSigs[j]);
					c1->TV = TV;
					c1->TVC = TVC;
					c1->TVNC = TVNC;
					C2->confs.push_back(c1);
					
					//cout<<Ci->getFlipflop(i)->getOutput(0)->getName()<<":"<<TV<<endl;
                                        tracedSigs.pop_back();
				}
			}	
		}

		C2->min();
		C2->reduce();
		swap(C1,C2);
                
	}
	
        tracedSigs.clear();	
        initSigs();
        C1->rank();
        //looking at the top k ones
        ofstream out("Rank_List");
        out<<"Rank List Starts...."<<endl;
        for(int i=0; i<C1->confs.size(); ++i){
                out<<"Signal Index: "<<C1->confs[i]->tracedSigs[0]->getIndex()<<"\t";
                out<<"TV: "<<C1->confs[i]->TV<<"\t";
                out<<"TVNC: "<<C1->confs[i]->TVNC<<endl;
        }
        
        C1->min();
        C1->reduce();
	
        int mc = C1->maxTV();
        for(int k2=0; k2<C1->confs[0]->tracedSigs.size(); ++k2){
                tracedSigs.push_back(C1->confs[0]->tracedSigs[k2]);
                C1->confs[0]->tracedSigs[k2]->setTraced(true);
        }
        TV = C1->confs[0]->TV;
        TVC = C1->confs[0]->TVC;
        TVNC = C1->confs[0]->TVNC;
	
	return;	
}
#else
void Algorithm::traceSelect(unsigned n){

	Confset *C1,*C2;
	C2 = new Confset();
	C1 = new Confset();
	Conf *c1;
	
	for(int i=0; i<Ci->flipflopSize(); ++i){
                if( (!Ci->getFlipflop(i)->getOutput(0)->getTraced())){
                        
                        tracedSigs.push_back(Ci->getFlipflop(i)->getOutput(0));
                        visCompute();
                        c1 = new Conf();
                        //cout<<"pushed signals are "<<endl;
                        
                        for(int j=0; j<tracedSigs.size(); ++j)
                        {
                                //cout<<tracedSigs[j]->getName()<<"\t";
                                c1->tracedSigs.push_back(tracedSigs[j]);
                        }
                        //cout<<endl;
                        
                        c1->TV = TV;
                        c1->TVC = TVC;
                        c1->TVNC = TVNC;
                        
                        //cout<<"TV is "<<TV<<endl;
                        //cout<<"TVC is "<<TVC<<endl;
                        //cout<<"TVNC is "<<TVNC<<endl;
                        
                        C1->confs.push_back(c1);
                        tracedSigs.pop_back();
                        
                }
        }	
	
        C1->min();
        C1->reduce();
        int mc = C1->maxTV();
        tracedSigs.clear();
        cout<<"mc is "<<mc<<endl;
        cout<<"mc should be 0 !!"<<endl;
        
        for(int k2=0; k2<C1->confs[mc]->tracedSigs.size(); ++k2){
                tracedSigs.push_back(C1->confs[mc]->tracedSigs[k2]);
                C1->confs[mc]->tracedSigs[k2]->setTraced(true);
        }
        
        TV = C1->confs[mc]->TV;
        TVC = C1->confs[mc]->TVC;
        TVNC = C1->confs[mc]->TVNC;
	
	return;	
}
#endif
